
package com.twohalf.mifty.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.thrift.TException;

import club.jmint.crossing.exception.CrossException;
import club.jmint.mifty.crossing.ServiceCall;
import club.jmint.mifty.dao.Sql;
import club.jmint.mifty.log.MyLog;
import club.jmint.mifty.service.MiftyService;

import com.google.gson.JsonObject;
import com.twohalf.mifty.service.gen.PaymentService.Iface;

public class PaymentServiceImpl extends MiftyService implements Iface {
	private IIdBuilder ib = new IndexBasedIdBuilder();
	private String dbName = "db_twohalf";
	private String transTable = dbName+".t_transaction";
	private Sql ddl = Sql.getInstance();
	
	@Override
	public Map<String, String> payCreate(Map<String, String> params) throws TException {
		HashMap<String, String> resultMap = new HashMap<String, String>();
		
		//create a unique transanction id
		String id = Integer.toString(ib.generateTransactionIdx());
		params.put("id", id);
		
		int erows = ddl.sqlCreate(transTable, params);
		if (erows<0){
			MyLog.logger.error("transanction add failed.");
			resultMap.put("errorCode", Integer.toString(ErrorCode.TWOHALF_DB_OPERATION_FAILED.getCode()));
			resultMap.put("errorInfo", ErrorCode.TWOHALF_DB_OPERATION_FAILED.getInfo());
			return resultMap;			
		}
		else if (erows==0){
		}
		else {
			MyLog.logger.info("added transaction: " + id);
		}
		
		resultMap.put("id", id);
		return resultMap;

	}

	@Override
	public Map<String, String> payDelete(Map<String, String> params) throws TException {
		HashMap<String, String> resultMap = new HashMap<String, String>();
		String id = params.get("id");
		String condition = "id='"+id+"'";
		
		int erows = ddl.sqlDelete(transTable, condition);
		if (erows<0){
			MyLog.logger.error("transaction delete failed.");
			resultMap.put("errorCode", Integer.toString(ErrorCode.TWOHALF_DB_OPERATION_FAILED.getCode()));
			resultMap.put("errorInfo", ErrorCode.TWOHALF_DB_OPERATION_FAILED.getInfo());
			return resultMap;			
		}
		else if (erows==0){
			MyLog.logger.warn("transaction not exists: " + id);
			resultMap.put("errorCode", Integer.toString(ErrorCode.TWOHALF_OBJECT_NOT_EXIST.getCode()));
			resultMap.put("errorInfo", ErrorCode.TWOHALF_OBJECT_NOT_EXIST.getInfo());
			return resultMap;
		}
		else{
			MyLog.logger.info("deleted transaction: " + id);
		}
		
		return resultMap;

	}

	@Override
	public Map<String, String> payUpdate(Map<String, String> params) throws TException {
		HashMap<String, String> resultMap = new HashMap<String, String>();
		String id = params.get("id");
		String condition = "id='"+id+"'";
		
		int erows = ddl.sqlUpdate(transTable, params, condition);
		if (erows<0){
			MyLog.logger.error("transaction update failed.");
			resultMap.put("errorCode", Integer.toString(ErrorCode.TWOHALF_DB_OPERATION_FAILED.getCode()));
			resultMap.put("errorInfo", ErrorCode.TWOHALF_DB_OPERATION_FAILED.getInfo());
			return resultMap;			
		} else if (erows==0){
			MyLog.logger.warn("transaction not exists: " + id);
			resultMap.put("errorCode", Integer.toString(ErrorCode.TWOHALF_OBJECT_NOT_EXIST.getCode()));
			resultMap.put("errorInfo", ErrorCode.TWOHALF_OBJECT_NOT_EXIST.getInfo());
			return resultMap;			
		} else {
			MyLog.logger.info("updated transaction: " + id);
		}
		
		resultMap.put("id", id);
		return resultMap;
	}

	@Override
	public Map<String, String> payInfoQuery(Map<String, String> params) throws TException {
		HashMap<String, String> resultMap = new HashMap<String, String>();
		String id = params.get("id");
		String condition = "id='"+id+"'";
		
		String fields = params.get("fields");
		String[] fieldlist = fields.split(",");
		
		List<Object[]> list = ddl.sqlSelect(transTable, fields, condition);
		if (list.isEmpty()){
			MyLog.logger.warn("transaction not exists: " + id);
			resultMap.put("errorCode", Integer.toString(ErrorCode.TWOHALF_OBJECT_NOT_EXIST.getCode()));
			resultMap.put("errorInfo", ErrorCode.TWOHALF_OBJECT_NOT_EXIST.getInfo());
			return resultMap;			
		}
		MyLog.logger.info("query transaction: " + id);
		
		Object[] obj = list.get(0);
		for (int i=0;i<fieldlist.length;i++){
			resultMap.put(fieldlist[i], Sql.getSqlResultFieldAsString(obj[i]));
		}
		return resultMap;

	}

	@Override
	public Map<String, String> payListQuery(Map<String, String> params) throws TException {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * Payment callback, called when payment completed from 3rd pay channel, 
	 * this callback will be triggered by 3rd pay system via front web interface
	 * @param transaction_id
	 * @param order_id
	 * @param amount
	 * @param payer_id
	 * @param payer_name
	 * @param pay_3rdno
	 * @param pay_time
	 * @param pay_channel
	 * @param status
	 * @return errorCode
	 */
	@Override
	public Map<String, String> payCallback(Map<String, String> params) throws TException {
		HashMap<String, String> resultMap = new HashMap<String, String>();
		String id = params.get("transaction_id");
		String condition = "id="+id;
		
		int erows = ddl.sqlUpdate(transTable, params, condition);
		if (erows<0){
			MyLog.logger.error("transaction update failed.");
			resultMap.put("errorCode", Integer.toString(ErrorCode.TWOHALF_DB_OPERATION_FAILED.getCode()));
			resultMap.put("errorInfo", ErrorCode.TWOHALF_DB_OPERATION_FAILED.getInfo());
			return resultMap;			
		} else if (erows==0){
			MyLog.logger.warn("transaction not exists: " + id);
			resultMap.put("errorCode", Integer.toString(ErrorCode.TWOHALF_OBJECT_NOT_EXIST.getCode()));
			resultMap.put("errorInfo", ErrorCode.TWOHALF_OBJECT_NOT_EXIST.getInfo());
			return resultMap;			
		} else {
			MyLog.logger.info("updated transaction: " + id);
		}
		
		//call order service to update order pay status
		ServiceCall sc = new ServiceCall();
		
		JsonObject jo = new JsonObject();
		jo.addProperty("transaction_id", id);
		jo.addProperty("order_id", params.get("order_id"));
		jo.addProperty("pay_status", Constants.PAY_STATUS_SUCCESS);
		jo.addProperty("pay_time", params.get("pay_time"));
		String ret;
		try {
			ret = sc.invoke("TwohalfServer@com.two.half.mifty.service.gen.OrderService@orderCallback", jo.toString());
		} catch (CrossException e) {
			MyLog.logger.error("order call back failed.");
			MyLog.printStackTrace(e);
			//error will be handled some time later.
		}
		
	
		return resultMap;
	}

}

